/*
 * Utilidaes.java
 *
 * Created on 31 de agosto de 2007, 03:16 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package ig.formato.util;

import ig.formato.dto.CampoPlanoDTO;
import ig.formato.dto.CampoPreprocesamientoDTO;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Properties;

/**
 * Clase utilitaria para hacer cosas varia.
 * je je je
 * 
 * @author jsanchez
 */
public class Utilidades {


    public static String NUMERICO = "Numerico";
    public static String FECHA = "Fecha";
    public static String CARACTER = "Caracter";
    
    /**
     * convierte un blob a String
     * @param obj
     * @return
     */
    public static String convertBlobToString(Object obj) throws SQLException, IOException {
        //Pendiente - El cambio en todo slo que utilizan esta conversion
        if ( obj == null ) {
            return "";
        }
        
        if (obj instanceof String) {
            return obj.toString();
        }
        StringBuilder builder = new StringBuilder("");
        InputStream inStream = null;
        inStream = ((Blob) obj).getBinaryStream();
        int size = (int) ((Blob) obj).length();
        byte[] buffer = new byte[size];
        while ( size > 0 && (inStream.read(buffer)) != -1) {
            builder.append(new String(buffer));
        }
        return builder.toString();
    }

    /**
     * Convierte un Arreglo en Colection
     * @param data
     * @return
     */
    public static Collection convertir(Object[][] data) {
        Collection c = new ArrayList();
        for (int i = 0; i < data.length; i++) {
            c.add(data[i][0]);
        }
        return c;
    }

    /**
     * convierte una Collection en un Hastable
     *
     * @param c
     * @param metodoKey
     * @param value
     * @return
     * @throws java.lang.IllegalAccessException
     * @throws java.lang.reflect.InvocationTargetException
     */
    public static java.util.Hashtable convertir(Collection c, String metodoKey, String value) throws IllegalAccessException, InvocationTargetException {
        java.util.Hashtable h = new java.util.Hashtable();
        Object[] o = new Object[0];
        if (c != null) {
            for (Object obj : c) {
                java.lang.reflect.Method[] met = obj.getClass().getMethods();
                Object _key = null;
                Object _value = null;
                for (int i = 0; i < met.length; i++) {
                    if (met[i].getName().equals(metodoKey)) {
                        _key = met[i].invoke(obj, o);
                    }
                    if (value.equals("OBJ")) {
                        _value = obj;
                    } else if (met[i].getName().equals(value)) {
                        _value = met[i].invoke(obj, o);
                    }
                    if (_key != null && _value != null) {
                        break;
                    }
                }
                if (_key != null) {
                    h.put(_key, _value);
                }
            }
        }
        return h;
    }

    /**
     * Convierte un Hashtable en una Collection
     *
     * @param ht
     * @return
     */
    public static java.util.Collection convertir(java.util.Hashtable ht) {
        java.util.Collection cc = new ArrayList();
        Enumeration enumm = ht.elements();
        while (enumm.hasMoreElements()) {
            cc.add(enumm.nextElement());
        }
        return cc;
    }

    /**
     * Convierte ubn objeto en un Entero
     * @param obj
     * @return
     */
    public static Integer getInteger(Object obj) {
        if (obj instanceof Integer) {
            return (Integer) obj;
        } else if (obj instanceof Double) {
            return ((Double) obj).intValue();
        } else if (obj instanceof BigDecimal) {
            return ((BigDecimal) obj).intValue();
        } else if (obj instanceof Long) {
            return ((Long) obj).intValue();
        } else if (obj instanceof String) {
            return Integer.valueOf(obj.toString());
        }
        return null;
    }

    /**
     * Calcula el MD5 de una cadena
     *
     * @param cadena
     * @return
     */
    public static String MD5(String cadena) {
        return Utilidades.diges("MD5", cadena);
    }

    /**
     * Calcula el Diges de una cadena,
     * puede ser MD5, SHA-1, etc
     * @param Modo
     * @param cadena
     * @return
     */
    public static String diges(String Modo, String cadena) {
        try {
            MessageDigest M_hash = MessageDigest.getInstance(Modo);
            byte[] Hash = null;
            M_hash.update(cadena.getBytes());
            Hash = M_hash.digest();

            StringBuffer StrBuff = new StringBuffer();

            for (int i = 0; i < Hash.length; i++) {
                String s = Integer.toHexString(Hash[i]);
                int length = s.length();
                if (length >= 2) {
                    StrBuff.append(s.substring(length - 2, length));
                } else {
                    StrBuff.append("0");
                    StrBuff.append(s);
                }
            }

            return StrBuff.toString();
        } catch (NoSuchAlgorithmException e) {
            System.out.println("Error en JCA");
            return null;
        }
    }

    /**
     * Dice que tipo de dato es un valor
     * Numerico, Caracter, Fecha
     * @param obj
     * @return
     * @throws ig.formato.util.IGFormatoException
     */
    public static String getFormato(String obj) throws IGFormatoException {
        if (obj == null) {
            return "";
        } else if (obj.equals("java.math.BigDecimal") || obj.equals("Numerico")) {
            return "Numerico";
        } else if (obj.equals("java.math.BigDecimal") || obj.equals("Numerico")) {
            return "Numerico";
        } else if (obj.equals("java.lang.Integer") || obj.equals("Numerico")) {
            return "Numerico";
        } else if (obj.equals("java.lang.Long") || obj.equals("Numerico")) {
            return "Numerico";
        } else if (obj.equals("java.lang.String") || obj.equals("Caracter")) {
            return "Caracter";
        } else if (obj.equals("java.lang.Double") || obj.equals("Numerico")) {
            return "Numerico";
        } else if (obj.equals("java.util.Date") || obj.equals("java.sql.Timestamp") || obj.equals("java.sql.Date") || obj.equals("oracle.sql.DATE") || obj.equals("oracle.sql.TIMESTAMP") || obj.equals("Fecha")) {
            return "Fecha";
        } else {
            System.out.println("obj.getClass().getName():"+obj);
            throw new IGFormatoException("Tipo de dato indefinido", "defina el tipo el formato para este tipo de dato:" + obj.getClass().getName());
        }
    }



    /**
     * Dice el tipo de datos segun el numero el java.sql.Type
     * @param i
     * @return
     * @throws ig.formato.util.IGFormatoException
     */
    public static String getTiposDatos(int i) throws IGFormatoException {
        switch (i) {
            case 3:
                return "java.lang.Double";
            case 4:
                return "java.lang.Integer";
            case 6:
                return "java.lang.Float";
            case 8:
                return "java.lang.Double";
            case 2:
                return "java.lang.Double";
            case 1:
                return "java.lang.String";
            case 12:
                return "java.lang.String";
            case 91:
                return "java.util.Date";
            case 92:
                return "java.util.Date";
            case 93:
                return "java.util.Date";
            case 16:
                return "java.util.Boolean";
            case -5:
                return "java.lang.Integer";
            case 7:
                return "java.lang.Double";
            case 2005:
                // d = null;
                return "java.lang.String";
                

//                public final static int BIT 		=  -7;
//                public final static int TINYINT 	=  -6;
//                public final static int SMALLINT	=   5;
//                public final static int INTEGER 	=   4;
//                public final static int BIGINT 		=  -5;
//                public final static int FLOAT 		=   6;
//                public final static int REAL 		=   7;
//                public final static int DOUBLE 		=   8;
//                public final static int NUMERIC 	=   2;
//                public final static int DECIMAL		=   3;
//                public final static int CHAR		=   1;
//                public final static int VARCHAR 	=  12;
//                public final static int LONGVARCHAR 	=  -1;
//                public final static int DATE 		=  91;
//                public final static int TIME 		=  92;
//                public final static int TIMESTAMP 	=  93;
//                public final static int BINARY		=  -2;
//                public final static int VARBINARY 	=  -3;
//                public final static int LONGVARBINARY 	=  -4;
//                public final static int NULL		=   0;
//                public final static int OTHER		= 1111;
//                public final static int JAVA_OBJECT         = 2000;
//                public final static int DISTINCT            = 2001;
//                public final static int STRUCT              = 2002;
//                public final static int ARRAY               = 2003;
//                public final static int BLOB                = 2004;
//                public final static int CLOB                = 2005;
//                public final static int REF                 = 2006;
//                public final static int DATALINK = 70;
//                public final static int BOOLEAN = 16;
        }
        throw new IGFormatoException("El tipo de datos con id [" + i + "] no esta configurada", "Envíe este mensaje y la estrucutra de la tabla al proveedor.");
    }

    /**
     * aplica la configuracion por defecto segun el tipo de dato
     * @param _dto
     */
    public static String setConfDefault(Object _dto) throws IGFormatoException {


        String classs = null;
        if (_dto instanceof CampoPlanoDTO) {
            classs = Utilidades.getFormato(((CampoPlanoDTO) _dto).configuracionDTO().getClasse());
        } else if (_dto instanceof CampoPreprocesamientoDTO) {
            classs = Utilidades.getFormato(((CampoPreprocesamientoDTO) _dto).getClasse());
        }

        String key = classs.equals("Caracter") ? "conf/campoCaracter.properties" : (classs.equals("Numerico") ? "conf/campoNumero.properties" : "conf/campoFecha.properties");
        Properties pro = LoadProperties.loadPropertiess(key);

        String _object = pro.getProperty("object");
        String justificar = pro.getProperty("justificar");
        String longitud = pro.getProperty("longitud");
        String separador = pro.getProperty("separador");
        String validaciones = pro.getProperty("validaciones");
        String truncar = pro.getProperty("truncar");
        String relleno = pro.getProperty("relleno");
        String RETURN="Defauld: ";
        if (_dto instanceof CampoPlanoDTO) {
            ((CampoPlanoDTO) _dto).configuracionDTO().setJustificado(justificar != null && !justificar.equals("") ? Integer.valueOf(justificar) : 0);
            ((CampoPlanoDTO) _dto).configuracionDTO().setLongitud(longitud != null && !longitud.equals("") ? Integer.valueOf(longitud) : 0);
            ((CampoPlanoDTO) _dto).configuracionDTO().setSeparadorDecimal(separador != null && !separador.equals("") ? separador : "");
            ((CampoPlanoDTO) _dto).configuracionDTO().setTruncar(truncar != null && !truncar.equals("") ? Integer.valueOf(truncar) : 0);
            ((CampoPlanoDTO) _dto).configuracionDTO().setRelleno(relleno != null && !relleno.equals("") ? relleno : "");
            ((CampoPlanoDTO) _dto).configuracionDTO().setObject(_object != null && !_object.equals("") ? _object : "");
            ((CampoPlanoDTO) _dto).setValidacionAdicional(validaciones != null && !validaciones.equals("") ? validaciones : "");
        } else if (_dto instanceof CampoPreprocesamientoDTO) {
            if (classs.equals("Numerico") && (((CampoPreprocesamientoDTO) _dto).getSeparadorDecimal() == null || ((CampoPreprocesamientoDTO) _dto).getSeparadorDecimal().equals(""))) {
                ((CampoPreprocesamientoDTO) _dto).setSeparadorDecimal(separador != null && !separador.equals("") ? separador : "");
                RETURN+="[Separador Decimal]";
            }

            if (((CampoPreprocesamientoDTO) _dto).getObjeto() == null || ((CampoPreprocesamientoDTO) _dto).getObjeto().equals("")) {
                if (classs.equals("Caracter")) {
                    ((CampoPreprocesamientoDTO) _dto).setObjeto("Igual");
                    RETURN+="[Convertir a]";
                } else {
                    ((CampoPreprocesamientoDTO) _dto).setObjeto(_object != null && !_object.equals("") ? _object : "");
                    if (classs.equals("Fecha")) {
                        RETURN+="[Formato]";
                    }else{
                        RETURN+=", [Decimales]";
                    }
                }
            }            
        }
        return !RETURN.equals("Defauld: ")?RETURN:"";
    }

    /**
     * Redondea un valor aun numero especificado de decimales
     * @param numero
     * @param decimales
     * @return
     */
    public static double redondear(double numero, int decimales) {
        return Math.round(numero * Math.pow(10, decimales)) / Math.pow(10, decimales);
    }

}


